static void dispatch_rw_block_io(struct task_struct *p, int index);
static void dispatch_probe_blk(struct task_struct *p, int index);
static void dispatch_probe_seg(struct task_struct *p, int index);
+static void dispatch_probe_seg_all(struct task_struct *p, int index);
static void dispatch_debug_block_io(struct task_struct *p, int index);
static void dispatch_create_segment(struct task_struct *p, int index);
static void dispatch_delete_segment(struct task_struct *p, int index);
dispatch_probe_seg(p, i);
break;
+ case XEN_BLOCK_PROBE_SEG_ALL:
+ dispatch_probe_seg_all(p, i);
+ break;
+
case XEN_BLOCK_DEBUG:
dispatch_debug_block_io(p, i);
break;
make_response(p, blk_ring->ring[index].req.id, XEN_BLOCK_PROBE_BLK, rc);
}
-static void dispatch_probe_seg(struct task_struct *p, int index)
+static void dispatch_probe_seg_common(struct task_struct *p,
+ struct task_struct *target,
+ int type,
+ int index)
{
extern void xen_segment_probe(struct task_struct *, xen_disk_info_t *);
spin_unlock_irqrestore(&p->page_lock, flags);
xdi = phys_to_virt(buffer);
- xen_segment_probe(p, xdi);
+ xen_segment_probe(target, xdi);
unlock_buffer(p, buffer, sizeof(xen_disk_info_t), 1);
out:
- make_response(p, blk_ring->ring[index].req.id, XEN_BLOCK_PROBE_SEG, rc);
+ make_response(p, blk_ring->ring[index].req.id, type, rc);
+}
+
+static void dispatch_probe_seg(struct task_struct *p, int index)
+{
+ dispatch_probe_seg_common(p, p, XEN_BLOCK_PROBE_SEG, index);
+}
+
+static void dispatch_probe_seg_all(struct task_struct *p, int index)
+{
+ dispatch_probe_seg_common(p, NULL, XEN_BLOCK_PROBE_SEG_ALL, index);
}
static void dispatch_rw_block_io(struct task_struct *p, int index)
for ( loop = 0; loop < XEN_MAX_SEGMENTS; loop++ )
{
if ( (xsegments[loop].mode == XEN_SEGMENT_UNUSED) ||
- (xsegments[loop].domain != p->domain) )
+ (p && xsegments[loop].domain != p->domain) )
continue;
device = MK_VIRTUAL_XENDEV(xsegments[loop].segment_number);
#define XEN_BLOCK_PHYSDEV_GRANT 10 /* grant access to range of disk blocks */
#define XEN_BLOCK_PHYSDEV_PROBE 11 /* probe for a domain's physdev
accesses */
+#define XEN_BLOCK_PROBE_SEG_ALL 12 /* prove for every domain's segments,
+ not just ours. */
/* NB. Ring size must be small enough for sizeof(blk_ring_t) <= PAGE_SIZE. */
#define BLK_RING_SIZE 64
case XEN_BLOCK_PHYSDEV_PROBE:
case XEN_BLOCK_PROBE_BLK:
case XEN_BLOCK_PROBE_SEG:
+ case XEN_BLOCK_PROBE_SEG_ALL:
if ( RING_FULL ) return 1;
phys_device = (kdev_t) 0;
sector_number = 0;
case XEN_BLOCK_SEG_CREATE:
case XEN_BLOCK_SEG_DELETE:
case XEN_BLOCK_PROBE_SEG:
+ case XEN_BLOCK_PROBE_SEG_ALL:
case XEN_BLOCK_PROBE_BLK:
case XEN_BLOCK_PHYSDEV_GRANT:
case XEN_BLOCK_PHYSDEV_PROBE:
#include "xl_block.h"
#include <linux/proc_fs.h>
#include <linux/delay.h>
+#include <linux/seq_file.h>
static struct proc_dir_entry *vhd;
extern unsigned short xldev_to_physdev(kdev_t xldev);
-static int proc_read_vhd(char *page, char **start, off_t off,
- int count, int *eof, void *data)
+static void *proc_vhd_next(struct seq_file *s, void *v, loff_t *pos)
{
+ xen_disk_info_t *data;
+
+ if ( pos != NULL )
+ ++(*pos);
+
+ data = v;
+ return data->count-- ? NULL : v;
+}
+
+static void *proc_vhd_start(struct seq_file *s, loff_t *ppos)
+{
+ loff_t pos = *ppos;
+ xen_disk_info_t *data;
+
+ data = kmalloc(sizeof(*data), GFP_KERNEL);
+ xenolinux_control_msg(XEN_BLOCK_PROBE_SEG_ALL, (char *)data, sizeof(*data));
+ data->count -= pos;
+
+ if (data->count > 0)
+ return data;
+
+ kfree(data);
+ return NULL;
+}
+
+static int proc_vhd_show(struct seq_file *s, void *v)
+{
+ xen_disk_info_t *data = v;
+
+ seq_printf (s,
+ "%4x %4x %lx\n",
+ data->disks[data->count - 1].device,
+ data->disks[data->count - 1].type,
+ data->disks[data->count - 1].capacity);
+
return 0;
}
+static void proc_vhd_stop(struct seq_file *s, void *v)
+{
+ kfree(v);
+}
+
+static struct seq_operations proc_vhd_op = {
+ .start = proc_vhd_start,
+ .next = proc_vhd_next,
+ .show = proc_vhd_show,
+ .stop = proc_vhd_stop
+};
+
+static int proc_open_vhd(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &proc_vhd_op);
+}
+
+
#define isdelim(c) \
(c==' '||c==','||c=='\n'||c=='\r'||c=='\t'||c==':'||c=='('||c==')' ? 1 : 0)
}
static int proc_write_vhd(struct file *file, const char *buffer,
- unsigned long count, void *data)
+ size_t count, loff_t *offp)
{
char *local = kmalloc((count + 1) * sizeof(char), GFP_KERNEL);
char *string;
return res;
}
+static struct file_operations proc_vhd_operations = {
+ open: proc_open_vhd,
+ read: seq_read,
+ llseek: seq_lseek,
+ release: seq_release,
+ write: proc_write_vhd
+};
+
/******************************************************************/
int __init xlseg_proc_init(void)
panic ("xlseg_init: unable to create vhd proc entry\n");
}
vhd->data = NULL;
- vhd->read_proc = proc_read_vhd;
- vhd->write_proc = proc_write_vhd;
+ vhd->proc_fops = &proc_vhd_operations;
vhd->owner = THIS_MODULE;
printk(KERN_ALERT "XenoLinux Virtual Disk Device Monitor installed\n");